package cn.swunet.schat.service;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.sql.Time;

import com.mysql.fabric.xmlrpc.base.Data;

/**
 * 
 * @author: arosen.swunet@qq.com
 *
 * @date: 2020年5月1日
 *
 * @TDDO: 由 PacketHandlerWorker 创建， 用来发送数据
 */
public class PacketSender{
	
	//待发送的数据
	private DatagramPacket packet;
	//UDP Socket
	private DatagramSocket socket;

	/**
	 * 发送数据给指定host并返回发送是否成功
	 * @param byte[] data 要发送的数据
	 * @param userActiveIp	目标IP
	 * @param userActivePort	目标 port
	 */
	public PacketSender(byte[] data, String userActiveIp, int userActivePort) {
		try {
			this.socket = new DatagramSocket();
			this.packet = new DatagramPacket(data, 0, data.length, InetAddress.getByName(userActiveIp), userActivePort);
		} catch (SocketException e) {
			System.out.println("Send Worker Socket DatagramSocket Constructe Failed!");
		} catch (UnknownHostException e1) {
			System.out.println("Send Worker Socket DatagramPacket Constructe Failed!");
		}
	}

	/**
	 * 发送数据，5S超时重传 重传5次
	 * @author:arosen.swunet@qq.com
	 * @return:boolean	数据是否发送成功
	 */
	public boolean doSend(boolean isReply){
		int count = 0;
		boolean isSuccess = false;
		//超时重传机制，5s超时，重传三次，失败后返回失败
		while(true) {
			try {
				//发送数据
				socket.send(packet);
				
				//不需要重传
				if (!isReply) {
					isSuccess = true;
					break;
				}
				
				//设置超时
				this.socket.setSoTimeout(5_000);
				//接收响应
				socket.receive(packet);
				count++;
			} catch (IOException e) {
				if(count < 5)
					continue;
				else 
					break;
			}
			
			//解析响应
			byte[] data = packet.getData();
			if (data[2] == PacketHandlerWorker.SC_ACK) {
				isSuccess = true;
				break;
			}
		}
		return isSuccess;
	}	
	/**
	 * 使用重传机制 
	 * @author:arosen.swunet@qq.com
	 * @return:boolean
	 */
	public boolean doSend(){
		return this.doSend(true);
	}
}
